package com.pai4j.message.interceptor;

import com.pai4j.message.core.interceptor.MessageInterceptor;
import com.pai4j.message.model.MessageContext;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Component;

import jakarta.annotation.PostConstruct;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import java.util.regex.Pattern;

/**
 * 敏感词拦截器
 * 检测消息内容中的敏感词，防止违规内容发送
 * 
 * 支持敏感词库配置和正则匹配
 *
 * @author PAI4J Team
 * @date 2025-11-01
 */
@Slf4j
@Component
@ConditionalOnProperty(prefix = "pai4j.message.interceptors.sensitive", name = "enabled", havingValue = "true", matchIfMissing = false)
public class SensitiveWordInterceptor implements MessageInterceptor {

    /**
     * 敏感词库（实际项目中应从配置文件或数据库加载）
     */
    private Set<String> sensitiveWords = new HashSet<>();

    /**
     * 敏感词正则模式
     */
    private Pattern sensitivePattern;

    @PostConstruct
    public void init() {
        // 初始化敏感词库（示例）
        sensitiveWords.addAll(Arrays.asList(
            "暴力", "色情", "赌博", "政治敏感词"
            // 实际项目中应从配置或数据库加载
        ));

        // 编译敏感词正则
        if (!sensitiveWords.isEmpty()) {
            String regex = String.join("|", sensitiveWords);
            sensitivePattern = Pattern.compile(regex, Pattern.CASE_INSENSITIVE);
        }

        log.info("敏感词拦截器初始化完成: 敏感词数量={}", sensitiveWords.size());
    }

    @Override
    public String getName() {
        return "sensitive-word";
    }

    @Override
    public boolean intercept(MessageContext context) {
        String content = context.getContent();
        
        // 内容为空，直接通过
        if (StringUtils.isBlank(content)) {
            return true;
        }

        try {
            // 检查敏感词
            if (containsSensitiveWord(content)) {
                log.warn("消息包含敏感词，拦截发送: sender={}, receiver={}, content={}", 
                        context.getSenderId(), context.getReceiverId(), maskContent(content));
                
                // 可以选择：1.拦截 2.替换敏感词 3.记录并通过
                /**
                 *   TODO: 后续这里需要做更智能的判断，首先先判断是否包含系统敏感词，如：暴力、色情、赌博等，
                 *   如果包含则不允许通过，其次增加字典服务,用户自定义敏感词，然后通过字典服务进行匹配，如果匹配到则不允许通过或者替换成****显示
                 *
                 * @author: CYM-pai
                 * @date: 2025/11/06 18:19
                 **/
                
                return false;
            }

            log.debug("敏感词检查通过");
            return true;

        } catch (Exception e) {
            log.error("敏感词检查异常，允许通过: error={}", e.getMessage(), e);
            return true; // 异常时允许通过
        }
    }

    @Override
    public int getOrder() {
        return 20; // 第二优先级
    }

    /**
     * 检查是否包含敏感词
     */
    private boolean containsSensitiveWord(String content) {
        if (sensitivePattern != null) {
            return sensitivePattern.matcher(content).find();
        }

        // 简单匹配
        for (String word : sensitiveWords) {
            if (content.contains(word)) {
                return true;
            }
        }

        return false;
    }

    /**
     * 掩码显示内容（用于日志）
     */
    private String maskContent(String content) {
        if (content == null || content.length() <= 20) {
            return content;
        }
        return content.substring(0, 20) + "...";
    }

    /**
     * 替换敏感词（可选功能）
     */
    public String replaceSensitiveWords(String content) {
        if (sensitivePattern != null) {
            return sensitivePattern.matcher(content).replaceAll("***");
        }
        
        String result = content;
        for (String word : sensitiveWords) {
            result = result.replace(word, "***");
        }
        return result;
    }

    /**
     * 添加敏感词
     */
    public void addSensitiveWord(String word) {
        if (StringUtils.isNotBlank(word)) {
            sensitiveWords.add(word);
            // 重新编译正则
            init();
        }
    }

    @Override
    public String getDescription() {
        return "敏感词拦截器 - 检测并拦截包含敏感词的消息";
    }
}

